package handler

import (
	"html/template"
	"log"
	"net/http"
	"path/filepath"
	"strconv"
	"strings"

	"pgm/internal/config"
	"pgm/internal/introspect"

	"github.com/gin-gonic/gin"
)

// WebHandler Web页面处理器
type WebHandler struct {
	inspector *introspect.Inspector
}

// NewWebHandler 创建Web处理器
func NewWebHandler() *WebHandler {
	return &WebHandler{
		inspector: introspect.NewInspector(),
	}
}

// Index 首页
func (h *WebHandler) Index(c *gin.Context) {
	tables, err := h.inspector.GetTables("public")
	if err != nil {
		c.HTML(http.StatusInternalServerError, "error.html", gin.H{
			"Title": "错误",
			"Error": "获取表列表失败: " + err.Error(),
		})
		return
	}

	c.HTML(http.StatusOK, "index.html", gin.H{
		"Title":  "PGM - PostgreSQL管理平台",
		"Tables": tables,
	})
}

// TableView 表视图页面
func (h *WebHandler) TableView(c *gin.Context) {
	tableName := c.Param("tableName")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))

	table, err := h.inspector.GetTableByName(tableName, "public")
	if err != nil {
		c.HTML(http.StatusNotFound, "error.html", gin.H{
			"Title": "错误",
			"Error": "表不存在: " + err.Error(),
		})
		return
	}

	c.HTML(http.StatusOK, "table_view.html", gin.H{
		"Title":     "表管理 - " + tableName,
		"Table":     table,
		"TableName": tableName,
		"Page":      page,
		"PageSize":  pageSize,
	})
}

// TableCreate 创建记录页面
func (h *WebHandler) TableCreate(c *gin.Context) {
	tableName := c.Param("tableName")

	table, err := h.inspector.GetTableByName(tableName, "public")
	if err != nil {
		c.HTML(http.StatusNotFound, "error.html", gin.H{
			"Title": "错误",
			"Error": "表不存在: " + err.Error(),
		})
		return
	}

	c.HTML(http.StatusOK, "table_create.html", gin.H{
		"Title":     "新增记录 - " + tableName,
		"Table":     table,
		"TableName": tableName,
	})
}

// TableEdit 编辑记录页面
func (h *WebHandler) TableEdit(c *gin.Context) {
	tableName := c.Param("tableName")
	id := c.Param("id")

	table, err := h.inspector.GetTableByName(tableName, "public")
	if err != nil {
		c.HTML(http.StatusNotFound, "error.html", gin.H{
			"Title": "错误",
			"Error": "表不存在: " + err.Error(),
		})
		return
	}

	c.HTML(http.StatusOK, "table_edit.html", gin.H{
		"Title":     "编辑记录 - " + tableName,
		"Table":     table,
		"TableName": tableName,
		"ID":        id,
	})
}

// SetupRoutes 设置路由
func SetupRoutes(r *gin.Engine) {
	// 创建模板函数映射
	funcMap := template.FuncMap{
		"contains": func(haystack interface{}, needle string) bool {
			switch h := haystack.(type) {
			case []string:
				for _, s := range h {
					if s == needle {
						return true
					}
				}
				return false
			case string:
				return strings.Contains(h, needle)
			default:
				return false
			}
		},
		"hasPrefix": func(s, prefix string) bool {
			return strings.HasPrefix(s, prefix)
		},
		"hasSuffix": func(s, suffix string) bool {
			return strings.HasSuffix(s, suffix)
		},
		"upper": strings.ToUpper,
		"lower": strings.ToLower,
		"or": func(args ...bool) bool {
			for _, arg := range args {
				if arg {
					return true
				}
			}
			return false
		},
		"and": func(args ...bool) bool {
			for _, arg := range args {
				if !arg {
					return false
				}
			}
			return true
		},
	}

	// 设置模板路径并加载模板函数
	templatePath := filepath.Join(config.AppConfig.Web.TemplatePath, "*.html")
	log.Printf("模板路径: %s", templatePath)
	tmpl := template.Must(template.New("").Funcs(funcMap).ParseGlob(templatePath))
	r.SetHTMLTemplate(tmpl)

	// 设置静态文件路径
	r.Static("/static", config.AppConfig.Web.StaticPath)

	// 创建处理器实例
	apiHandler := NewAPIHandler()
	webHandler := NewWebHandler()

	// Web页面路由
	web := r.Group("/")
	{
		web.GET("/", webHandler.Index)
		web.GET("/table/:tableName", webHandler.TableView)
		web.GET("/table/:tableName/create", webHandler.TableCreate)
		web.GET("/table/:tableName/edit/:id", webHandler.TableEdit)
	}

	// API路由
	api := r.Group("/api")
	{
		// 表管理
		tables := api.Group("/tables")
		{
			tables.GET("/", apiHandler.GetTables)
			tables.GET("/:tableName", apiHandler.GetTable)
			tables.GET("/:tableName/stats", apiHandler.GetTableStats)
		}

		// 数据管理
		data := api.Group("/data")
		{
			data.GET("/:tableName", apiHandler.GetRecords)
			data.GET("/:tableName/:id", apiHandler.GetRecord)
			data.POST("/:tableName", apiHandler.CreateRecord)
			data.PUT("/:tableName/:id", apiHandler.UpdateRecord)
			data.DELETE("/:tableName/:id", apiHandler.DeleteRecord)
			data.DELETE("/:tableName/batch", apiHandler.BatchDelete)
		}
	}
}
